package com.alibaba.citrus.ots.sales.plan.facade.service.setting.contract;

import com.alibaba.acm.shaded.com.alibaba.metrics.StringUtils;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.model.ImportRequest;
import com.alibaba.citrus.ots.sales.plan.api.setting.contract.DepartmentContractRedFileService;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.contract.DepartContractRedImportRequest;
import com.alibaba.citrus.ots.sales.plan.facade.service.SalesPlanCommonService;
import com.alibaba.citrus.ots.sales.plan.facade.service.SalesPlanOutCommonService;
import com.alibaba.citrus.ots.sales.plan.model.enums.ContractStatDimensionEnum;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.result.Result;
import com.epoch.app.bcots.model.dto.DepartmentContractRedLineLoadListRequest;
import com.epoch.app.bcots.model.dto.ScItemSDO;
import com.epoch.app.bcots.sales_plan.contract.dto.BatchQueryByCustomerAddressAndScItemRequest;
import com.epoch.app.bcots.sales_plan.contract.dto.BatchQueryByCustomerAddressAndScItemResponse;
import com.epoch.app.bcots.sales_plan.contract.model.Contract;
import com.epoch.app.bcots.sales_plan.contract.service.ContractService;
import com.epoch.app.bcots.sales_plan.departmentcontractredline.dto.BatchCreateRedRatiosRequest;
import com.epoch.app.bcots.sales_plan.departmentcontractredline.model.DepartmentContractRedLine;
import com.epoch.app.bcots.sales_plan.departmentcontractredline.service.DepartmentContractRedLineService;
import com.epoch.app.otsplatformenhance.sdo.OrganizationSDO;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author wangyibing
 */
@Component
public class DepartContractRedIFileServiceImpl implements DepartmentContractRedFileService {

    @Resource
    private SalesPlanCommonService salesPlanCommonService;

    @Resource
    private ContractService contractService;

    @Resource
    private DepartmentContractRedLineService departmentContractRedLineService;

    @Resource
    private SalesPlanOutCommonService salesPlanOutCommonService;

    @Override
    @FacadeInvoker
    public Result<List<DepartContractRedImportRequest>> departContractRedImport(List<DepartContractRedImportRequest> requestList) {
        if (CollectionUtils.isEmpty(requestList)) {
            return Result.success(Lists.newArrayList());
        }
        Set<String> yearSet = requestList.stream().map(DepartContractRedImportRequest::getContractYear).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
        Set<String> departOutCodes = requestList.stream().map(DepartContractRedImportRequest::getOrgSalesDepartmentCode).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
        Set<String> scItemOutIds = requestList.stream().map(DepartContractRedImportRequest::getScItemId).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
        //部门编码转换为id
        Map<String, OrganizationSDO> mapByOutCode = salesPlanOutCommonService.getOrganizationMapByOutCode(departOutCodes);
        if (Objects.isNull(mapByOutCode) || CollectionUtils.isEmpty(mapByOutCode.values())) {
            return Result.success(ImportRequest.setRequestErrorMessage(requestList, ErrorMessage.code("OTS-01-003-01-16-003", null).getDisplayErrorMessage()));
        }
        List<String> departIds = mapByOutCode.values().stream().map(OrganizationSDO::getId).collect(Collectors.toList());
        //货品编码转换为id
        Map<String, ScItemSDO> itemMapByOutId = salesPlanOutCommonService.getScItemMapByOutId(scItemOutIds);
        if (Objects.isNull(itemMapByOutId) || CollectionUtils.isEmpty(itemMapByOutId.values())) {
            return Result.success(ImportRequest.setRequestErrorMessage(requestList, ErrorMessage.code("OTS-01-005-02-15-002", null).getDisplayErrorMessage()));

        }
        List<String> scItemIds = itemMapByOutId.values().stream().map(ScItemSDO::getScItemId).collect(Collectors.toList());
        List<String> contractYears = Lists.newArrayList(yearSet);
        List<Contract> contracts = new ArrayList<>();
        for (String year : contractYears) {
            BatchQueryByCustomerAddressAndScItemRequest scItemRequest = BatchQueryByCustomerAddressAndScItemRequest.builder().build();
            scItemRequest.setOrgSalesDepartmentCodes(departIds);
            scItemRequest.setScItemIds(scItemIds);
            scItemRequest.setContractYear(year);
            scItemRequest.setType(ContractStatDimensionEnum.DEPARTMENT_SC_ITEM.getCode());
            BatchQueryByCustomerAddressAndScItemResponse response = contractService.batchQueryByCustomerAddressAndScItem(scItemRequest);
            if (Objects.isNull(response) || CollectionUtils.isEmpty(response.getResult())) {
                continue;
            }
            contracts.addAll(response.getResult());
        }

        if (CollectionUtils.isEmpty(contracts)) {
            return Result.success(ImportRequest.setRequestErrorMessage(requestList, ErrorMessage.code("OTS-02-001-00-15-007", null).getDisplayErrorMessage()));
        }
        Set<String> haveContractYear = contracts.stream().map(Contract::getContractYear).collect(Collectors.toSet());
        //将合同量的部门和货品的outerCode获取到
        Set<String> haveDepartCodes = contracts.stream().map(Contract::getOrgSalesDepartmentCode).collect(Collectors.toSet());
        Set<String> haveScItems = contracts.stream().map(Contract::getScItemId).collect(Collectors.toSet());
        Map<String, com.epoch.app.bcots.model.dto.OrganizationSDO> organizationMapByIds = salesPlanOutCommonService.getOrganizationMapByIds(haveDepartCodes);
        Map<String, ScItemSDO> scItemMapByIds = salesPlanOutCommonService.getScItemMapByIds(haveScItems,true);
        Set<String> haveDepartOutCode = organizationMapByIds.keySet();
        Set<String> haveScItemOuterIds = scItemMapByIds.keySet();


        List<DepartmentContractRedLine> addRequest = Lists.newArrayList();
        List<DepartmentContractRedLine> updateRequest = Lists.newArrayList();

        for (DepartContractRedImportRequest departRequest : requestList) {
            //判空
            if(StringUtils.isBlank(departRequest.getContractYear())){
                departRequest.setErrorMessage((ErrorMessage.code("OTS-02-001-00-16-032", null).getDisplayErrorMessage()));
                continue;
            }
            if(StringUtils.isBlank(departRequest.getOrgSalesDepartmentCode())){
                departRequest.setErrorMessage((ErrorMessage.code("OTS-02-001-00-16-033", null).getDisplayErrorMessage()));
                continue;
            }
            if(StringUtils.isBlank(departRequest.getScItemId())){
                departRequest.setErrorMessage((ErrorMessage.code("OTS-02-001-00-16-026", null).getDisplayErrorMessage()));
                continue;
            }
            if (!haveContractYear.contains(departRequest.getContractYear())) {
                departRequest.setErrorMessage((ErrorMessage.code("OTS-02-001-00-15-007", null).getDisplayErrorMessage()));
                continue;
            }
            if (!haveDepartOutCode.contains(departRequest.getOrgSalesDepartmentCode())) {
                departRequest.setErrorMessage((ErrorMessage.code("OTS-02-001-00-15-007", null).getDisplayErrorMessage()));
                continue;
            }
            if (!haveScItemOuterIds.contains(departRequest.getScItemId())) {
                departRequest.setErrorMessage((ErrorMessage.code("OTS-02-001-00-15-007", null).getDisplayErrorMessage()));
                continue;
            }

            //保存或更新
            DepartmentContractRedLineLoadListRequest loadListRequest = DepartmentContractRedLineLoadListRequest.newDepartmentContractRedLineLoadListRequestBuilder().build();
            loadListRequest.setOrgSalesDepartmentCode(organizationMapByIds.get(departRequest.getOrgSalesDepartmentCode()).getId());
            loadListRequest.setContractYear(departRequest.getContractYear());
            loadListRequest.setScItemId(scItemMapByIds.get(departRequest.getScItemId()).getScItemId());
            com.alibaba.lattice2.epoch.sdk.model.Result<List<DepartmentContractRedLine>> listResult = departmentContractRedLineService.loadDepartmentContractRedLineList(loadListRequest);
            DepartmentContractRedLine departmentContractRedLine = new DepartmentContractRedLine();
            BeanUtils.copyProperties(departRequest, departmentContractRedLine);
            departmentContractRedLine.setScItemId(scItemMapByIds.get(departRequest.getScItemId()).getScItemId());
            departmentContractRedLine.setOrgSalesDepartmentCode(organizationMapByIds.get(departRequest.getOrgSalesDepartmentCode()).getId());

            Contract contract = contracts.stream().filter(c -> c.getContractYear().equals(departRequest.getContractYear())
                    && c.getOrgSalesDepartmentCode().equals(organizationMapByIds.get(departRequest.getOrgSalesDepartmentCode()).getId())
                    && c.getScItemId().equals(scItemMapByIds.get(departRequest.getScItemId()).getScItemId())).findFirst().get();
            setRedCountAndRedRatio(contract, departmentContractRedLine);
            if (Objects.isNull(listResult) || CollectionUtils.isEmpty(listResult.getResult())) {
//                departmentContractRedLine.setGmtCreate(new Date());
//                departmentContractRedLine.setGmtModified(new Date());
                departmentContractRedLine.setGmt_create(new Date());
                departmentContractRedLine.setGmt_modified(new Date());
                addRequest.add(departmentContractRedLine);
            } else {
                DepartmentContractRedLine redLine = listResult.getResult().stream().findFirst().get();
                departmentContractRedLine.setId(redLine.getId());
//                departmentContractRedLine.setGmtCreate(new Date());
                departmentContractRedLine.setGmt_create(new Date());
                departmentContractRedLineService.updateDepartmentContractRedLine(departmentContractRedLine);
            }
        }

        if (CollectionUtils.isNotEmpty(addRequest)) {
            BatchCreateRedRatiosRequest redRatiosRequest = new BatchCreateRedRatiosRequest();
            redRatiosRequest.setDepartmentRedRatios(addRequest);
            departmentContractRedLineService.batchCreateRedRatios(redRatiosRequest);
        }

        return Result.success(requestList);
    }

    private void setRedCountAndRedRatio(Contract contract, DepartmentContractRedLine departmentContractRedLine) {
        if (Objects.nonNull(contract.getJanQuantity()) && Objects.nonNull(departmentContractRedLine.getJanRedRatio())) {
            departmentContractRedLine.setJanRedCount(new BigDecimal(contract.getJanQuantity() * departmentContractRedLine.getJanRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getFebQuantity()) && Objects.nonNull(departmentContractRedLine.getFebRedRatio())) {
            departmentContractRedLine.setFebRedCount(new BigDecimal(contract.getFebQuantity() * departmentContractRedLine.getFebRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());

        }
        if (Objects.nonNull(contract.getMarQuantity()) && Objects.nonNull(departmentContractRedLine.getMarRedRatio())) {
            departmentContractRedLine.setMarRedCount(new BigDecimal(contract.getMarQuantity() * departmentContractRedLine.getMarRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getAprQuantity()) && Objects.nonNull(departmentContractRedLine.getAprRedRatio())) {
            departmentContractRedLine.setAprRedCount(new BigDecimal(contract.getAprQuantity() * departmentContractRedLine.getAprRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getMayQuantity()) && Objects.nonNull(departmentContractRedLine.getMayRedRatio())) {
            departmentContractRedLine.setMayRedCount(new BigDecimal(contract.getMayQuantity() * departmentContractRedLine.getMayRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getJuneQuantity()) && Objects.nonNull(departmentContractRedLine.getJuneRedRatio())) {
            departmentContractRedLine.setJuneRedCount(new BigDecimal(contract.getJuneQuantity() * departmentContractRedLine.getJuneRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getJulyQuantity()) && Objects.nonNull(departmentContractRedLine.getJulyRedRatio())) {
            departmentContractRedLine.setJulyRedCount(new BigDecimal(contract.getJulyQuantity() * departmentContractRedLine.getJulyRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getAugQuantity()) && Objects.nonNull(departmentContractRedLine.getAugRedRatio())) {
            departmentContractRedLine.setAugRedCount(new BigDecimal(contract.getAugQuantity() * departmentContractRedLine.getAugRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getSeptQuantity()) && Objects.nonNull(departmentContractRedLine.getSeptRedRatio())) {
            departmentContractRedLine.setSeptRedCount(new BigDecimal(contract.getSeptQuantity() * departmentContractRedLine.getSeptRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getOctQuantity()) && Objects.nonNull(departmentContractRedLine.getOctRedRatio())) {
            departmentContractRedLine.setOctRedCount(new BigDecimal(contract.getOctQuantity() * departmentContractRedLine.getOctRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getNovQuantity()) && Objects.nonNull(departmentContractRedLine.getNovRedRatio())) {
            departmentContractRedLine.setNovRedCount(new BigDecimal(contract.getNovQuantity() * departmentContractRedLine.getNovRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contract.getDecQuantity()) && Objects.nonNull(departmentContractRedLine.getDecRedRatio())) {
            departmentContractRedLine.setDecRedCount(new BigDecimal(contract.getDecQuantity() * departmentContractRedLine.getDecRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());

        }

        departmentContractRedLine.setAnnualRedCount(departmentContractRedLine.getJanRedCount()
                + departmentContractRedLine.getFebRedCount()
                + departmentContractRedLine.getMarRedCount()
                + departmentContractRedLine.getAprRedCount()
                + departmentContractRedLine.getMayRedCount()
                + departmentContractRedLine.getJuneRedCount()
                + departmentContractRedLine.getJulyRedCount()
                + departmentContractRedLine.getAugRedCount()
                + departmentContractRedLine.getSeptRedCount()
                + departmentContractRedLine.getOctRedCount()
                + departmentContractRedLine.getNovRedCount()
                + departmentContractRedLine.getDecRedCount()
        );
    }
}
